#pragma once

#include <entt/entt.hpp>
#include <SDL.h>
#include "Resources.hpp"
#include "Editor.hpp"
#include "Game.hpp"
#include "SceneManager.hpp"
#include "ScriptManager.hpp"

enum class EngineMode : unsigned char {
    UndownEngineMode = 0,
    EditorEngineMode,
    GameEngineMode,
};

class Engine {
public:
    Engine();
    ~Engine();
    
    bool initialize(const char* title, int width, int height);
    void run();
    void shutdown();
    
    entt::registry& getRegistry();
    SDL_Renderer* getRenderer() { return renderer; }
    SDL_Window* getWindow() { return window; }
    
    entt::entity createEntity();
    void destroyEntity(entt::entity entity);
    
    Editor& getEditor() { return *editor; }

    SceneManager& getSceneManager() { return *m_sceneManager; }
    
    ScriptManager& getScriptManager() { return *m_scriptManager; }

    void setEngineMode(EngineMode mode) { engineMode = mode; }
private:
    void processInput();
    void update(float deltaTime);
    void render();
private:
    // app mode
    EngineMode engineMode;

    SDL_Window* window;
    SDL_Renderer* renderer;
    Editor* editor;
    Game* game;
    
    entt::registry registry;
    
    bool isRunning;
    Uint32 lastUpdateTime;

    std::unique_ptr<ScriptManager> m_scriptManager;
    std::unique_ptr<SceneManager> m_sceneManager;
    
    const int FPS = 60;
    const int FRAME_DELAY = 1000 / FPS;
};